package com.xiaoyi.equery;

import com.xiaoyi.analyzer.DataAnalyzer;
import com.xiaoyi.analyzer.DataAnalyzerFactory;

import com.xiaoyi.condition.*;
import com.xiaoyi.enums.DataBaseTypeEnum;
import com.xiaoyi.enums.ResultTypeAggEnum;
import com.xiaoyi.enums.ResultTypeEnum;
import com.xiaoyi.io.Resources;
import com.xiaoyi.parse.GenericTokenParser;
import com.xiaoyi.parse.TokenHandler;
import com.xiaoyi.pooled.PooledDataSource;
import com.xiaoyi.query.Query;
import com.xiaoyi.query.QueryFactory;
import com.xiaoyi.query.QueryPlugin;
import com.xiaoyi.query.SqlHolder;
import com.xiaoyi.type.TypeHandler;
import com.xiaoyi.type.TypeHandlerRegistry;

import java.net.MalformedURLException;
import java.sql.*;
import java.util.*;
/*

1. 参数元数据获取 SQL 语句参数格式
	通过 PreparedStatement 对象调用方法获取 参数元数据对象
		ParameterMetaData getParameterMetaData();
	通过 ParameterMetaData 对象调用方法 获取参数个数
		int getParameterCount();

2. 结果集元数据获取字段个数和字段名称
	通过 ResultSet 结果集对象调用方法获取结果集元数据对象
		ResultSetMetaData getMetaData();
	通过 ResultSetMetaData 结果集元数据对象获取字段个数
		int getColumnCount();
	通过 ResultSetMetaData 结果集元数据获取字段名称，【注意】字段下标从 1 开始
		String getColumnName(int columnIndex);



*
* */

/**
 * @author xiaoyi
 * @version 1.0.0
 * @createTime 2023-02-18 20:34:00
 */
public class EQuery {
    // 查询插件
    QueryPlugin headerQueryPlugin =new QueryPlugin() {
        QueryPlugin queryPlugin;
        @Override
        public void setQueryPlugin(QueryPlugin queryPlugin) {
            this.queryPlugin = queryPlugin;
        }
        @Override
        public SqlHolder beforeQuery(SqlHolder sql, ParamsModel paramsModel, EQueryModel eQueryModel) {
            return sql;
        }

        @Override
        public QueryResultModel afterQuery(QueryResultModel queryResultModel) {
            return queryResultModel;
        }
    } ;
    PooledDataSource pooledDataSource;

    public PooledDataSource getPooledDataSource() {
        return pooledDataSource;
    }

    public void setPooledDataSource(PooledDataSource pooledDataSource) {
        this.pooledDataSource = pooledDataSource;
    }

    public EQuery() {
        initQueryPlugin();
    }

    private synchronized void initQueryPlugin() {
        ServiceLoader<QueryPlugin>  queryPluginServiceLoader= ServiceLoader.load(QueryPlugin.class);
        Iterator<QueryPlugin> iterator = queryPluginServiceLoader.iterator();
        while (iterator.hasNext()){
            QueryPlugin next = iterator.next();
            next.setQueryPlugin(headerQueryPlugin);
            headerQueryPlugin = next;
        }
    }


    public  Object query(ParamsModel paramsModel ){
        // 获取配置
        PooledDataSource pooledDataSource = getConnection();
        EQueryModel eQueryModel = getCommonConfig(pooledDataSource, paramsModel.getModuleId());
        if (Objects.isNull(eQueryModel)){
            return "";
        }
        // 拿到配置信息就能去创建数据库链接，然后查询数据去了
        Integer databaseType = eQueryModel.getDatabaseType();
        DataBaseTypeEnum anEnum = DataBaseTypeEnum.getEnum(databaseType);
        if (Objects.isNull(anEnum)){
            return "";
        }
        QueryResultModel queryResultModel = null;
        Query query = QueryFactory.createQuery(anEnum);
        try {
            queryResultModel = query.excuteQuery(paramsModel, eQueryModel,headerQueryPlugin);
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
        if (Objects.isNull(queryResultModel)){
            return "";
        }
       return  analysis(eQueryModel, queryResultModel);
    }


    private static Object analysis(EQueryModel eQueryModel, QueryResultModel queryResultModel) {
        if (ResultTypeEnum.NORMAL_LIST.getValue().equals(eQueryModel.getResultType())){
            return queryResultModel.getQueryResultList();
        }else if (ResultTypeEnum.PAGE_LIST.getValue().equals(eQueryModel.getResultType())){
             return queryResultModel;
        }else if (ResultTypeEnum.AGGREGATE_RESULT.getValue().equals(eQueryModel.getResultType())){
            ResultTypeAggEnum anEnum = ResultTypeAggEnum.getEnum(eQueryModel.getResultTypeAgg());
            if (Objects.isNull(anEnum)){
                return queryResultModel.getQueryResultList();
            }
            DataAnalyzer dataAnalyzer = DataAnalyzerFactory.getDataAnalyzer(anEnum);
            if (Objects.isNull(dataAnalyzer)){
                return queryResultModel.getQueryResultList();
            }
            return dataAnalyzer.analysis(eQueryModel,queryResultModel);

        }
        return queryResultModel.getQueryResultList();
    }




    /*
     * 查询配置
     * @author xiaoyi
     * @date 2023/2/18 23:07
     * @param null
     * @return
     * @version v1.0
     */
    public static EQueryModel getCommonConfig(PooledDataSource pooledDataSource, Long id) {
        String sql = "SELECT NAME,description,sql_template,database_type,query_type,result_type,result_type_agg,agg_field, driver_class,url,username,PASSWORD,driver_from,driver_url FROM e_query LEFT JOIN e_datasource ON e_query.datasource_id = e_datasource.id WHERE e_query.id =?";
        try {
            Connection connection = pooledDataSource.getConnection();
            PreparedStatement preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setInt(1, 1);
            ResultSet resultSet = preparedStatement.executeQuery();
            boolean next = resultSet.next();
            if (next) {
                EQueryModel eQueryModel = new EQueryModel();
                eQueryModel.setName(resultSet.getString("name"));
                eQueryModel.setDescription(resultSet.getString("description"));
                eQueryModel.setSqlTemplate(resultSet.getString("sql_template"));
                eQueryModel.setDatabaseType(resultSet.getInt("database_type"));
                eQueryModel.setQueryType(resultSet.getInt("query_type"));
                eQueryModel.setResultType(resultSet.getInt("result_type"));
                eQueryModel.setResultTypeAgg(resultSet.getInt("result_type_agg"));
                eQueryModel.setAggField(resultSet.getString("agg_field"));
                eQueryModel.setUrl(resultSet.getString("url"));
                eQueryModel.setDriverClass(resultSet.getString("driver_class"));
                eQueryModel.setUsername(resultSet.getString("username"));
                eQueryModel.setPassword(resultSet.getString("password"));
                eQueryModel.setDriverFrom(resultSet.getInt("driver_from"));
                eQueryModel.setDriverUrl(resultSet.getString("driver_url"));

                System.out.println(eQueryModel.toString());
                return eQueryModel;
            }
            resultSet.close();
            preparedStatement.close();
            connection.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
        }
        return null;
    }


    public static PooledDataSource getConnection() {
        PooledDataSource pooledDataSource = new PooledDataSource();
        pooledDataSource.setDriver("com.mysql.jdbc.Driver");
        pooledDataSource.setUrl("jdbc:mysql://127.0.0.1/xiaoyi?useUnicode=true&characterEncoding=utf8&useSSL=false&useInformationSchema=true&serverTimezone=UTC");
        pooledDataSource.setUsername("root");
        pooledDataSource.setPassword("123456");
        return pooledDataSource;
    }


}
